package com.wxw.BaseLibrary.tool;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.*;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.Base64;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.jetbrains.annotations.Nullable;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.io.*;
import java.lang.Math;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.Key;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * Created by david on 14-3-11.
 */
public class SystemTool {
    //key为abcdefghijklmnopqrstuvwx的Base64编码
//    public static byte[] SECURITY_KEY= Base64.decode("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4", Base64.DEFAULT);
//    public static byte[] SECURITY_IV = { 1, 2, 3, 4, 5, 6, 7, 8 };
    public static String TAG = "SystemTool";

    public static String getSDCardPath() {
        // 判断SDCard是否存在
        boolean sdExist = Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED);
        String path = "";
        if (sdExist) {
            // 获取SDCard的路径
            File sdFile = Environment.getExternalStorageDirectory();
            path = sdFile.getPath() + "/";
        } else {
            path = getPhoneStoragePath();
        }
        return path;
    }

    public static String getPhoneStoragePath() {
        String mnu = "/";
        try {
            File fMnu = new File(mnu);
            File[] files = fMnu.listFiles(new FileFilter() {
                @Override
                public boolean accept(File file) {
                    return file.isDirectory() && "storage".equals(file.getName());
                }
            });
            files = files[0].listFiles();
            if (files.length > 1) {
                String sd = "";
                if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                    sd = Environment.getExternalStorageDirectory().getPath();
                }
                File file = null;
                for (File f : files) {
                    if (!f.getPath().equals(sd) && f.getPath().indexOf("sdcard") > 0) {
                        file = f;
                        if (file.canWrite()) {
                            mnu = f.getPath() + "/";
                            break;
                        }
                    }
                }
                if (file != null && !file.canWrite()) {
                    mnu = sd + "/";
                }
            }
        } catch (Exception e) {

        }
        return mnu;
    }


    public static boolean deleteFile(String path) {
        boolean isok = true;
        try {
            File file = new File(path);
            isok = file.delete();
        } catch (Exception e) {
            isok = false;
        }
        return isok;
    }

    public static boolean deleteFiles(String path, final String filter) {
        boolean isok = true;
        try {
            File file = new File(path);
            if (file.isFile()) {
                isok = deleteFile(path);
            } else {
                File[] files = file.listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File file) {
                        return file.getPath().contains(filter);
                    }
                });
                for (File f : files) {
                    if (f.isFile()) {
                        isok = isok && f.delete();
                    } else {
                        isok = deleteFiles(f.getAbsolutePath(), "");
                        if (isok) {
                            f.delete();
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            isok = false;
        }
        return isok;
    }

    public static <T> T getJsonObj(String jsonString, Class<T> cls) {
        T t = null;
        try {
            Gson gson = new Gson();
            t = gson.fromJson(jsonString, cls);
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            Log.e(TAG, e.getMessage());
        }
        return t;
    }

    @Nullable
    public static <T> List<T> getJsonObjs(String jsonString, Type type) {
        try {
            Gson gson = new Gson();
            return gson.fromJson(jsonString, type);
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, e.getMessage());
        }
        return null;
    }

    public static List<String> getList(String jsonString) {
        List<String> list = new ArrayList<String>();
        try {
            Gson gson = new Gson();
            list = gson.fromJson(jsonString, new TypeToken<List<String>>() {
            }.getType());
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            Log.e(TAG, e.getMessage());
        }
        return list;
    }

    public static List<Map<String, Object>> listKeyMaps(String jsonString) {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        try {
            Gson gson = new Gson();
            list = gson.fromJson(jsonString,
                    new TypeToken<List<Map<String, Object>>>() {
                    }.getType());
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            Log.e(TAG, e.getMessage());
        }
        return list;
    }

    public static String getLocalIpAddress() {
        String ip = "";
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface
                    .getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf
                        .getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (inetAddress instanceof Inet4Address && !inetAddress.isLoopbackAddress()) {
                        ip += inetAddress.getHostAddress().toString() + ",";
                    }
                }
            }
        } catch (SocketException ex) {
            Log.e(TAG, ex.toString());
        }
        return ip != null ? ip.substring(0, ip.length() - 1) : ip;
    }

    public static Bitmap generatorIcon(Bitmap icon, String text) {
        //初始化画布
        int iconSize = icon.getWidth();

        Bitmap contactIcon = Bitmap.createBitmap(icon.getWidth(), icon.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(contactIcon);

        //拷贝图片
        Paint iconPaint = new Paint();
        iconPaint.setDither(true);//防抖动
        iconPaint.setFilterBitmap(true);//用来对Bitmap进行滤波处理，这样，当你选择Drawable时，会有抗锯齿的效果
        Rect src = new Rect(0, 0, icon.getWidth(), icon.getHeight());
        Rect dst = new Rect(0, 0, icon.getWidth(), icon.getHeight());
        canvas.drawBitmap(icon, src, dst, iconPaint);

        int cirL, txtL;
        if (text.length() > 1) {
            cirL = iconSize - 15;
            txtL = iconSize - 26;
        } else {
            cirL = iconSize - 14;
            txtL = iconSize - 21;
        }
        //启用抗锯齿和使用设备的文本字距
        Paint countPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);
        countPaint.setColor(Color.parseColor("#EFD50B"));
        canvas.drawCircle(cirL, 15f, 13, countPaint);
        countPaint.setColor(Color.BLACK);
        countPaint.setTextSize(20f);
        countPaint.setTypeface(Typeface.DEFAULT_BOLD);
        canvas.drawText(text, txtL, 22, countPaint);
        return contactIcon;
    }

    /**
     * 对网络连接状态进行判断
     *
     * @return true, 可用； false， 不可用
     */
    @SuppressLint("MissingPermission")
    public static boolean isOpenNetwork(Context context) {
        ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connManager.getActiveNetworkInfo() != null) {
            return connManager.getActiveNetworkInfo().isAvailable();
        }
        return false;
    }

    public static String getVersionName(Context context) {
        if (context == null) {
            return "";
        }
        // 获取packagemanager的实例
        PackageManager packageManager = context.getPackageManager();
        try {
            // getPackageName()是你当前类的包名，0代表是获取版本信息
            PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
            String version = packInfo.versionName;
            return version;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    public static int getVersionCode(Context context) {
        if (context == null) {
            return -1;
        }
        // 获取packagemanager的实例
        PackageManager packageManager = context.getPackageManager();
        // getPackageName()是你当前类的包名，0代表是获取版本信息
        try {
            PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
            int vercode = packInfo.versionCode;
            return vercode;
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }

    }

    public static boolean checkVersion(String ver, Context context) {
        String[] vers = ver.split("\\.");
        String[] lvers = getVersionName(context).split("\\.");
        boolean b = true;
        for (int i = 0; i < 3; i++) {
            if (Integer.parseInt(vers[i]) == Integer.parseInt(lvers[i])) {
                b = true;
            } else if (Integer.parseInt(vers[i]) < Integer.parseInt(lvers[i])) {
                return true;
            } else {
                return false;
            }
        }
        b = b && getVersionCode(context) >= Integer.parseInt(vers[3]);
        return b;
    }

    public static boolean isInteger(String str) {
        String reg = "[-\\+]?[0-9]*";
        return str.matches(reg);
    }

    public static boolean isDouble(String str) {
        String reg = "[-\\+]?[0-9]*(\\.?)[0-9]*";
        return str.matches(reg);
    }

    public static int dp2px(int dp, Context context) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
                context.getResources().getDisplayMetrics());
    }

    /**
     * @param bitMap
     * @param maxSize 图片允许最大空间   单位：KB
     */
    public static Bitmap imageZoom(Bitmap bitMap, double maxSize) {
        //将bitmap放至数组中，意在bitmap的大小（与实际读取的原文件要大）
        if (bitMap == null) {
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitMap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        byte[] b = baos.toByteArray();
        //将字节换成KB
        double mid = b.length / 1024;
        //判断bitmap占用空间是否大于允许最大空间  如果大于则压缩 小于则不压缩
        if (mid > maxSize) {
            //获取bitmap大小 是允许最大大小的多少倍
            double i = mid / maxSize;
            //开始压缩  此处用到平方根 将宽带和高度压缩掉对应的平方根倍 （1.保持刻度和高度和原bitmap比率一致，压缩后也达到了最大大小占用空间的大小）
            bitMap = zoomImage(bitMap, bitMap.getWidth() / java.lang.Math.sqrt(i),
                    bitMap.getHeight() / Math.sqrt(i));
        }
        return bitMap;
    }

    /***
     * 图片的缩放方法
     *
     * @param bgimage
     *            ：源图片资源
     * @param newWidth
     *            ：缩放后宽度
     * @param newHeight
     *            ：缩放后高度
     * @return
     */
    public static Bitmap zoomImage(Bitmap bgimage, double newWidth, double newHeight) {
        // 获取这个图片的宽和高
        float width = bgimage.getWidth();
        float height = bgimage.getHeight();
        // 创建操作图片用的matrix对象
        Matrix matrix = new Matrix();
        // 计算宽高缩放率
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 缩放图片动作
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width,
                (int) height, matrix, true);
        if (!bgimage.isRecycled()) {
            bgimage.recycle();
            System.gc();
        }
        return bitmap;
    }

    public static Bitmap drawTextToBitmap(Context context, Bitmap bitmap, String text, int size, int color, int padding) {
        Bitmap.Config config = bitmap.getConfig();

        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(color);
        paint.setTextSize(dp2px(size, context));
        Rect bounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), bounds);
        paint.setDither(true);
        paint.setFilterBitmap(true);
        TextPaint textPaint = new TextPaint(paint);
        textPaint.setARGB(0xFF, 0xFF, 0, 0);
        StaticLayout layout = new StaticLayout(text, textPaint, 600, Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F, true);

        if (config == null) {
            config = Bitmap.Config.ARGB_8888;
        }
        bitmap = bitmap.copy(config, true);
        Canvas canvas = new Canvas(bitmap);
        int left = dp2px(padding, context);
        int top = dp2px(padding, context) + bounds.height();
        canvas.translate(left, top);
        layout.draw(canvas);

//        canvas.drawText(text, left, top, paint);
        return bitmap;
    }

    public static Bitmap drawTextToBitmap(Context context, Bitmap bitmap, String text, int size, int color) {
        return drawTextToBitmap(context, bitmap, text, size, color, 20);
    }

    public static File getTempFile(String fileName) {
        int po = fileName.lastIndexOf("/");
        if (po > 0 && po < fileName.length()) {
            return getTempFile(fileName.substring(0, po), fileName.substring(po + 1));
        } else {
            return getTempFile(getSDCardPath(), fileName);
        }
    }

    public static File getTempFile(String sPath, String fileName) {
// 指定文件路径为 外部存储 即sdcard。 文件夹名字为 项目包名。
        final File path = new File(sPath);
        if (!path.exists()) {
            path.mkdir();
        }
        return new File(path, fileName);
    }

    public static boolean checkEAN8BarCode(String barcode) {
        try {
            if (barcode.length() != 8) {
                return false;
            }
            int c1 = (Character.digit(barcode.charAt(0), 10) + Character.digit(barcode.charAt(2), 10)
                    + Character.digit(barcode.charAt(4), 10) + Character.digit(barcode.charAt(6), 10)) * 3;
            int c2 = Character.digit(barcode.charAt(1), 10) + Character.digit(barcode.charAt(3), 10) + Character.digit(barcode.charAt(5), 10);
            int cc = (c1 + c2) % 10;
            String s = (cc == 0 ? "0" : String.valueOf(10 - cc));
            return s.equals(barcode.substring(7));
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
            return false;
        }
    }

    public static boolean checkEAN13BarCode(String barcode) {
        try {
            if (barcode.length() != 13) {
                return false;
            }
            int c1 = (Character.digit(barcode.charAt(1), 10) + Character.digit(barcode.charAt(3), 10)
                    + Character.digit(barcode.charAt(5), 10) + Character.digit(barcode.charAt(7), 10)
                    + Character.digit(barcode.charAt(9), 10) + Character.digit(barcode.charAt(11), 10)) * 3;
            int c2 = Character.digit(barcode.charAt(0), 10) + Character.digit(barcode.charAt(2), 10)
                    + Character.digit(barcode.charAt(4), 10) + Character.digit(barcode.charAt(6), 10)
                    + Character.digit(barcode.charAt(8), 10) + Character.digit(barcode.charAt(10), 10);
            int cc = (c1 + c2) % 10;
            String s = (cc == 0 ? "0" : String.valueOf(10 - cc));
            return s.equals(barcode.substring(12));
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
            return false;
        }
    }

    /**
     * unicode 转字符串
     */
    public static String unicode2String(String unicode) {

        StringBuffer string = new StringBuffer();

        String[] hex = unicode.split("\\\\u");

        for (int i = 1; i < hex.length; i++) {

            // 转换出每一个代码点
            int data = Integer.parseInt(hex[i], 16);

            // 追加成string
            string.append((char) data);
        }

        return string.toString();
    }

    /**
     * 字符串转换unicode
     */
    public static String string2Unicode(String string) {

        StringBuffer unicode = new StringBuffer();

        for (int i = 0; i < string.length(); i++) {

            // 取出每一个字符
            char c = string.charAt(i);

            // 转换为unicode
            unicode.append("\\u" + Integer.toHexString(c));
        }

        return unicode.toString();
    }

    //状态栏高度
    public static int getStatusBarHeight(Context context) {
        Class<?> c = null;
        Object obj = null;
        Field field = null;
        int x = 0, statusBarHeight = 0;
        try {
            c = Class.forName("com.android.internal.R$dimen");
            obj = c.newInstance();
            field = c.getField("status_bar_height");
            x = Integer.parseInt(field.get(obj).toString());
            statusBarHeight = context.getResources().getDimensionPixelSize(x);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return statusBarHeight;
    }

    /**
     * 创建指定数量的随机字符串
     *
     * @param numberFlag 是否是数字
     * @param length
     * @return
     */
    public static String createRandom(boolean numberFlag, int length) {
        String retStr = "";
        String strTable = numberFlag ? "1234567890" : "1234567890abcdefghijkmnpqrstuvwxyz";
        int len = strTable.length();
        boolean bDone = true;
        do {
            retStr = "";
            int count = 0;
            for (int i = 0; i < length; i++) {
                double dblR = Math.random() * len;
                int intR = (int) Math.floor(dblR);
                char c = strTable.charAt(intR);
                if (('0' <= c) && (c <= '9')) {
                    count++;
                }
                retStr += strTable.charAt(intR);
            }
            if (count >= 2) {
                bDone = false;
            }
        } while (bDone);

        return retStr;
    }

    public static void startPhotograph(Activity activity, int requestCode) {
        startPhotograph(activity, false, requestCode);
    }

    public static void startPhotograph(Activity activity, String picName, int requestCode) {
        startPhotograph(activity, picName, false, requestCode);
    }

    public static void startPhotograph(Activity activity, boolean quick, int requestCode) {
        startPhotograph(activity, com.wxw.BaseLibrary.tool.SystemTool.createRandom(false, 10), quick, requestCode);
    }

    public static void startPhotograph(Activity activity, String picName, boolean quick, int requestCode) {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(SystemTool.getTempFile(picName)));
        if (quick) {
            intent.putExtra("android.intent.extra.quickCapture", true);//启用快捷拍照
        }
        activity.startActivityForResult(intent, requestCode);
    }

    public static Bitmap getBitmapFromMediaStore(Context context, String bitmapName, String fileName, float maxSize) {
        Bitmap bitmap = null;
        try {
            final File CameraImageFile = getTempFile(bitmapName);
            bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(),
                    Uri.fromFile(CameraImageFile));
            bitmap = SystemTool.imageZoom(bitmap, maxSize);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (fileName != null && !"".equals(fileName)) {
            FileOutputStream b = null;
            try {

                b = new FileOutputStream(fileName);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 50, b);// 把数据写入文件
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (b != null) {
                        b.flush();
                        b.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return bitmap;
    }

    public static void closeInputMethod(View view) {
        try {
            InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String formatString(String str, String key, String value) {
        int start = str.indexOf("[");
        int end = str.indexOf("]");
        if (start >= 0 && end >= 0 && end > start) {
            String skey = str.substring(start + 1, end);
            if (skey.equals(key)) {
                str = str.replace("[" + skey + "]", value);
            }
        }
        return str;
    }


    /**
     * 反射 禁止弹窗
     */
    public static void disableAPIDialog() {
        if (Build.VERSION.SDK_INT < 28) {
            return;
        }
        try {
            Class clazz = Class.forName("android.app.ActivityThread");
            Method currentActivityThread = clazz.getDeclaredMethod("currentActivityThread");
            currentActivityThread.setAccessible(true);
            Object activityThread = currentActivityThread.invoke(null);
            Field mHiddenApiWarningShown = clazz.getDeclaredField("mHiddenApiWarningShown");
            mHiddenApiWarningShown.setAccessible(true);
            mHiddenApiWarningShown.setBoolean(activityThread, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static boolean isBackground(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.processName.equals(context.getPackageName())) {
                if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
                    Log.i("后台", appProcess.processName);
                    return true;
                } else {
                    Log.i("前台", appProcess.processName);
                    return false;
                }
            }
        }
        return false;
    }
}
